using System;

namespace SDL
{
    public static unsafe partial class SDL2
    {
        internal const int SDLK_MASK = 1 << 30;
    }

    public enum Keycode
    {
        Unknown = 0,

        Return = '\r',
        Escape = 27,
        Backspace = '\b',
        Tab = '\t',
        Space = ' ',
        Exclaim = '!',
        Quotedbl = '"',
        Hash = '#',
        Percent = '%',
        Dollar = '$',
        Ampersand = '&',
        Quote = '\'',
        LeftParen = '(',
        RightParen = ')',
        Asterisk = '*',
        Plus = '+',
        Comma = ',',
        Minus = '-',
        Period = '.',
        Slash = '/',
        D0 = '0',
        D1 = '1',
        D2 = '2',
        D3 = '3',
        D4 = '4',
        D5 = '5',
        D6 = '6',
        D7 = '7',
        D8 = '8',
        D9 = '9',
        Colon = ':',
        SemiColon = ';',
        Less = '<',
        Equals = '=',
        Greater = '>',
        Question = '?',
        At = '@',
        /*
           Skip uppercase letters
         */
        LeftBracket = '[',
        Backslash = '\\',
        RightBracket = ']',
        Caret = '^',
        Underscore = '_',
        BackQuote = '`',
        A = 'a',
        B = 'b',
        C = 'c',
        D = 'd',
        E = 'e',
        F = 'f',
        G = 'g',
        H = 'h',
        I = 'i',
        J = 'j',
        K = 'k',
        L = 'l',
        M = 'm',
        N = 'n',
        O = 'o',
        P = 'p',
        Q = 'q',
        R = 'r',
        S = 's',
        T = 't',
        U = 'u',
        V = 'v',
        W = 'w',
        X = 'x',
        Y = 'y',
        Z = 'z',

        CapsLock = Scancode.CapsLock | SDL2.SDLK_MASK,

        F1 = Scancode.F1 | SDL2.SDLK_MASK,
        F2 = Scancode.F2 | SDL2.SDLK_MASK,
        F3 = Scancode.F3 | SDL2.SDLK_MASK,
        F4 = Scancode.F4 | SDL2.SDLK_MASK,
        F5 = Scancode.F5 | SDL2.SDLK_MASK,
        F6 = Scancode.F6 | SDL2.SDLK_MASK,
        F7 = Scancode.F7 | SDL2.SDLK_MASK,
        F8 = Scancode.F8 | SDL2.SDLK_MASK,
        F9 = Scancode.F9 | SDL2.SDLK_MASK,
        F10 = Scancode.F10 | SDL2.SDLK_MASK,
        F11 = Scancode.F11 | SDL2.SDLK_MASK,
        F12 = Scancode.F12 | SDL2.SDLK_MASK,

        PrintScreen = Scancode.PrintScreen | SDL2.SDLK_MASK,
        ScrollLock = Scancode.ScrollLock | SDL2.SDLK_MASK,
        Pause = Scancode.Pause | SDL2.SDLK_MASK,
        Insert = Scancode.Insert | SDL2.SDLK_MASK,
        Home = Scancode.Home | SDL2.SDLK_MASK,
        PageUp = Scancode.PageUp | SDL2.SDLK_MASK,
        Delete = 127,
        End = Scancode.End | SDL2.SDLK_MASK,
        PageDown = Scancode.PageDown | SDL2.SDLK_MASK,
        Right = Scancode.Right | SDL2.SDLK_MASK,
        Left = Scancode.Left | SDL2.SDLK_MASK,
        Down = Scancode.Down | SDL2.SDLK_MASK,
        Up = Scancode.Up | SDL2.SDLK_MASK,

        NumLockClear = Scancode.NumLockClear | SDL2.SDLK_MASK,
        KeyPadDivide = Scancode.KeyPadDivide | SDL2.SDLK_MASK,
        KeyPadMultiply = Scancode.KeyPadMultiply | SDL2.SDLK_MASK,
        KeyPadMinus = Scancode.KeyPadMinus | SDL2.SDLK_MASK,
        KeyPadPlus = Scancode.KeyPadPlus | SDL2.SDLK_MASK,
        KeyPadEnter = Scancode.KeyPadEnter | SDL2.SDLK_MASK,
        KeyPad1 = Scancode.KeyPad1 | SDL2.SDLK_MASK,
        KeyPad2 = Scancode.KeyPad2 | SDL2.SDLK_MASK,
        KeyPad3 = Scancode.KeyPad3 | SDL2.SDLK_MASK,
        KeyPad4 = Scancode.KeyPad4 | SDL2.SDLK_MASK,
        KeyPad5 = Scancode.KeyPad5 | SDL2.SDLK_MASK,
        KeyPad6 = Scancode.KeyPad6 | SDL2.SDLK_MASK,
        KeyPad7 = Scancode.KeyPad7 | SDL2.SDLK_MASK,
        KeyPad8 = Scancode.KeyPad8 | SDL2.SDLK_MASK,
        KeyPad9 = Scancode.KeyPad9 | SDL2.SDLK_MASK,
        KeyPad0 = Scancode.KeyPad0 | SDL2.SDLK_MASK,
        KeyPadPeriod = Scancode.KeyPadPeriod | SDL2.SDLK_MASK,

        Application = Scancode.Application | SDL2.SDLK_MASK,
        Power = Scancode.Power | SDL2.SDLK_MASK,
        KeyPadEquals = Scancode.KeyPadEquals | SDL2.SDLK_MASK,
        F13 = Scancode.F13 | SDL2.SDLK_MASK,
        F14 = Scancode.F14 | SDL2.SDLK_MASK,
        F15 = Scancode.F15 | SDL2.SDLK_MASK,
        F16 = Scancode.F16 | SDL2.SDLK_MASK,
        F17 = Scancode.F17 | SDL2.SDLK_MASK,
        F18 = Scancode.F18 | SDL2.SDLK_MASK,
        F19 = Scancode.F19 | SDL2.SDLK_MASK,
        F20 = Scancode.F20 | SDL2.SDLK_MASK,
        F21 = Scancode.F21 | SDL2.SDLK_MASK,
        F22 = Scancode.F22 | SDL2.SDLK_MASK,
        F23 = Scancode.F23 | SDL2.SDLK_MASK,
        F24 = Scancode.F24 | SDL2.SDLK_MASK,
        Execute = Scancode.Execute | SDL2.SDLK_MASK,
        Help = Scancode.Help | SDL2.SDLK_MASK,
        Menu = Scancode.Menu | SDL2.SDLK_MASK,
        Select = Scancode.Select | SDL2.SDLK_MASK,
        Stop = Scancode.Stop | SDL2.SDLK_MASK,
        Again = Scancode.Again | SDL2.SDLK_MASK,
        Undo = Scancode.Undo | SDL2.SDLK_MASK,
        Cut = Scancode.Cut | SDL2.SDLK_MASK,
        Copy = Scancode.Copy | SDL2.SDLK_MASK,
        Paste = Scancode.Paste | SDL2.SDLK_MASK,
        Find = Scancode.Find | SDL2.SDLK_MASK,
        Mute = Scancode.Mute | SDL2.SDLK_MASK,
        VolumeUp = Scancode.VolumeUp | SDL2.SDLK_MASK,
        VolumeDown = Scancode.VolumeDown | SDL2.SDLK_MASK,
        KeyPadComma = Scancode.KeyPadComma | SDL2.SDLK_MASK,
        KeyPadEqualsAS400 = Scancode.KeyPadEqualsAS400 | SDL2.SDLK_MASK,

        AltErase = Scancode.AltErase | SDL2.SDLK_MASK,
        SysReq = Scancode.SysReq | SDL2.SDLK_MASK,
        Cancel = Scancode.Cancel | SDL2.SDLK_MASK,
        Clear = Scancode.Clear | SDL2.SDLK_MASK,
        Prior = Scancode.Prior | SDL2.SDLK_MASK,
        Return2 = Scancode.Return2 | SDL2.SDLK_MASK,
        Separator = Scancode.Separator | SDL2.SDLK_MASK,
        Out = Scancode.Out | SDL2.SDLK_MASK,
        Oper = Scancode.Oper | SDL2.SDLK_MASK,
        ClearAgain = Scancode.ClearAgain | SDL2.SDLK_MASK,
        CrSel = Scancode.CrSel | SDL2.SDLK_MASK,
        ExSel = Scancode.ExSel | SDL2.SDLK_MASK,

        KeyPad00 = Scancode.KeyPad00 | SDL2.SDLK_MASK,
        KeyPad000 = Scancode.KeyPad000 | SDL2.SDLK_MASK,
        ThousandsSeparator = Scancode.ThousandsSeparator | SDL2.SDLK_MASK,
        DecimalSeparator = Scancode.DecimalSeparator | SDL2.SDLK_MASK,
        CurrencyUnit = Scancode.CurrencyUnit | SDL2.SDLK_MASK,
        CurrencySubunit = Scancode.CurrencySubunit | SDL2.SDLK_MASK,
        KeyPadLeftParen = Scancode.KeyPadLeftParen | SDL2.SDLK_MASK,
        KeyPadRightParen = Scancode.KeyPadRightParen | SDL2.SDLK_MASK,
        KeyPadLeftBrace = Scancode.KeyPadLeftBrace | SDL2.SDLK_MASK,
        KeyPadRightBrace = Scancode.KeyPadRightBrace | SDL2.SDLK_MASK,
        KeyPadTab = Scancode.KeyPadTab | SDL2.SDLK_MASK,
        KeyPadBackspace = Scancode.KeyPadBackspace | SDL2.SDLK_MASK,
        KeyPadA = Scancode.KeyPadA | SDL2.SDLK_MASK,
        KeyPadB = Scancode.KeyPadB | SDL2.SDLK_MASK,
        KeyPadC = Scancode.KeyPadC | SDL2.SDLK_MASK,
        KeyPadD = Scancode.KeyPadD | SDL2.SDLK_MASK,
        KeyPadE = Scancode.KeyPadE | SDL2.SDLK_MASK,
        KeyPadF = Scancode.KeyPadF | SDL2.SDLK_MASK,
        KeyPadXor = Scancode.KeyPadXor | SDL2.SDLK_MASK,
        KeyPadPower = Scancode.KeyPadPower | SDL2.SDLK_MASK,
        KeyPadPercent = Scancode.KeyPadPercent | SDL2.SDLK_MASK,
        KeyPadLess = Scancode.KeyPadLess | SDL2.SDLK_MASK,
        KeyPadGreater = Scancode.KeyPadGreater | SDL2.SDLK_MASK,
        KeyPadAmpersand = Scancode.KeyPadAmpersand | SDL2.SDLK_MASK,
        KeyPadDoubleAmpersand = Scancode.KeyPadDoubleAmpersand | SDL2.SDLK_MASK,
        KeyPadVerticalBar = Scancode.KeyPadVerticalBar | SDL2.SDLK_MASK,
        KeyPadDoubleVerticalBar = Scancode.KeyPadDoubleVerticalBar | SDL2.SDLK_MASK,
        KeyPadColon = Scancode.KeyPadColon | SDL2.SDLK_MASK,
        KeyPadHash = Scancode.KeyPadHash | SDL2.SDLK_MASK,
        KeyPadSpace = Scancode.KeyPadSpace | SDL2.SDLK_MASK,
        KeyPadAt = Scancode.KeyPadAt | SDL2.SDLK_MASK,
        KeyPadExclam = Scancode.KeyPadExclam | SDL2.SDLK_MASK,
        KeyPadMemStore = Scancode.KeyPadMemStore | SDL2.SDLK_MASK,
        KeyPadMemRecall = Scancode.KeyPadMemRecall | SDL2.SDLK_MASK,
        KeyPadMemClear = Scancode.KeyPadMemClear | SDL2.SDLK_MASK,
        KeyPadMemAdd = Scancode.KeyPadMemAdd | SDL2.SDLK_MASK,
        KeyPadMemSubtract = Scancode.KeyPadMemSubtract | SDL2.SDLK_MASK,
        KeyPadMemMultiply = Scancode.KeyPadMemMultiply | SDL2.SDLK_MASK,
        KeyPadMemDivide = Scancode.KeyPadMemDivide | SDL2.SDLK_MASK,
        KeyPadPlusMinus = Scancode.KeyPadPlusMinus | SDL2.SDLK_MASK,
        KeyPadClear = Scancode.KeyPadClear | SDL2.SDLK_MASK,
        KeyPadClearEntry = Scancode.KeyPadClearEntry | SDL2.SDLK_MASK,
        KeyPadBinary = Scancode.KeyPadBinary | SDL2.SDLK_MASK,
        KeyPadOctal = Scancode.KeyPadOctal | SDL2.SDLK_MASK,
        KeyPadDecimal = Scancode.KeyPadDecimal | SDL2.SDLK_MASK,
        KeyPadHexadecimal = Scancode.KeyPadHexadecimal | SDL2.SDLK_MASK,

        LCtrl = Scancode.LCtrl | SDL2.SDLK_MASK,
        LShift = Scancode.LShift | SDL2.SDLK_MASK,
        LAlt = Scancode.LAlt | SDL2.SDLK_MASK,
        LGui = Scancode.LGui | SDL2.SDLK_MASK,
        RCtrl = Scancode.RCtrl | SDL2.SDLK_MASK,
        RShift = Scancode.RShift | SDL2.SDLK_MASK,
        RAlt = Scancode.RAlt | SDL2.SDLK_MASK,
        RGui = Scancode.RGui | SDL2.SDLK_MASK,

        Mode = Scancode.Mode | SDL2.SDLK_MASK,

        AudioNext = Scancode.AudioNext | SDL2.SDLK_MASK,
        AudioPrev = Scancode.AudioPrev | SDL2.SDLK_MASK,
        AudioStop = Scancode.AudioStop | SDL2.SDLK_MASK,
        AudioPlay = Scancode.AudioPlay | SDL2.SDLK_MASK,
        AudioMute = Scancode.AudioMute | SDL2.SDLK_MASK,
        MediaSelect = Scancode.MediaSelect | SDL2.SDLK_MASK,
        Www = Scancode.Www | SDL2.SDLK_MASK,
        Mail = Scancode.Mail | SDL2.SDLK_MASK,
        Calculator = Scancode.Calculator | SDL2.SDLK_MASK,
        Computer = Scancode.Computer | SDL2.SDLK_MASK,
        AcSearch = Scancode.AcSearch | SDL2.SDLK_MASK,
        AcHome = Scancode.AcHome | SDL2.SDLK_MASK,
        AcBack = Scancode.AcBack | SDL2.SDLK_MASK,
        AcForward = Scancode.AcForward | SDL2.SDLK_MASK,
        AcStop = Scancode.AcStop | SDL2.SDLK_MASK,
        AcRefresh = Scancode.AcRefresh | SDL2.SDLK_MASK,
        AcBookmarks = Scancode.AcBookmarks | SDL2.SDLK_MASK,

        BrightnessDown = Scancode.BrightnessDown | SDL2.SDLK_MASK,
        BrightnessUp = Scancode.BrightnessUp | SDL2.SDLK_MASK,
        DisplaySwitch = Scancode.DisplaySwitch | SDL2.SDLK_MASK,
        KbdIllumToggle = Scancode.KbdIllumToggle | SDL2.SDLK_MASK,
        KbdIllumDown = Scancode.KbdIllumDown | SDL2.SDLK_MASK,
        KbdIllumUp = Scancode.KbdIllumUp | SDL2.SDLK_MASK,
        Eject = Scancode.Eject | SDL2.SDLK_MASK,
        Sleep = Scancode.Sleep | SDL2.SDLK_MASK,
        App1 = Scancode.App1 | SDL2.SDLK_MASK,
        App2 = Scancode.App2 | SDL2.SDLK_MASK,

        AudioRewind = Scancode.AudioRewind | SDL2.SDLK_MASK,
        AudioFastForward = Scancode.AudioFastForward | SDL2.SDLK_MASK
    }

    [Flags]
    public enum KeyModifier : ushort
    {
        None = 0x0000,
        LeftShift = 0x0001,
        RightShift = 0x0002,
        LeftCtrl = 0x0040,
        RightCtrl = 0x0080,
        LeftAlt = 0x0100,
        RightAlt = 0x0200,
        LeftGui = 0x0400,
        RightGui = 0x0800,
        Num = 0x1000,
        Caps = 0x2000,
        Mode = 0x4000,
        Reserved = 0x8000,

        Ctrl = LeftCtrl | RightCtrl,
        Shift = LeftShift | RightShift,
        Alt = LeftAlt | RightAlt,
        Gui = LeftGui | RightGui
    }
}
